package com.example.graduate.service.Impl;

import com.alibaba.fastjson.JSONObject;
import com.example.graduate.conf.Exception.AccountException;
import com.example.graduate.conf.Exception.OrderException;
import com.example.graduate.dto.*;
import com.example.graduate.env.*;
import com.example.graduate.mapper.OrderMapper;
import com.example.graduate.mapper.RechargeSerialMapper;
import com.example.graduate.mapper.UserMapper;
import com.example.graduate.pojo.RechargeSerial;
import com.example.graduate.pojo.ShopOrder;
import com.example.graduate.pojo.User;
import com.example.graduate.response.DataResponse;
import com.example.graduate.service.UserService;
import com.example.graduate.sort.RechargeSerialCreateTimeComparator;
import com.example.graduate.util.UuidUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserMapper userMapper;

    @Autowired
    UuidUtils uuidUtils;

    @Autowired
    RechargeSerialMapper rechargeSerialMapper;

    @Autowired
    OrderMapper orderMapper;

    @Override
    public DataResponse login(LoginRequest request) {
        User user = null;
        try {
            user = userMapper.getUser(request.getUsername());
        } catch (Exception e) {
            throw new OrderException(ResponseCodeEnum.SYSTEM_ERROR.getCode());
        }
        log.info("【登录接口】登陆用户：{}", JSONObject.toJSONString(user));
        if (user == null) {
            log.info("【登录接口】账号不存在");
            return new DataResponse(ResponseCodeEnum.COUNT_NOT_EXIST.getCode());
        }
        if (request.getPassword().equals(user.getPassword())) {
            if (!UserRowFlagCodeEnum.USABLE.getCode().equals(user.getRowFlag())) {
                log.info("【登录接口】账号已冻结");
                return new DataResponse(ResponseCodeEnum.COUNT_FREEZE.getCode());
            }
            log.info("【登录接口】成功登录");
            return new DataResponse(user.getId(), uuidUtils.getToken(user.getId().toString()), ResponseCodeEnum.success.getCode());
        } else {
            log.info("【登录接口】密码错误");
            return new DataResponse(ResponseCodeEnum.PASSWORD_ERROR.getCode());
        }
    }

    @Override
    public Double getBalance(User user) {

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DataResponse addBalance(RechargeRequest rechargeRequest) {
        try {
            userMapper.updateBalanceByUserId(rechargeRequest.getUserId(), rechargeRequest.getMoney());
            rechargeSerialMapper.insertRechargeSerial(OperationTypeEnum.TOPEE.getCode(), rechargeRequest.getMoney(),rechargeRequest.getUserId());
        } catch (Exception e) {
            log.error("【充值接口】系统异常{}:",e.getMessage());
            throw new OrderException(ResponseCodeEnum.CHECK_SYSTEM.getCode());
        }
        return new DataResponse(uuidUtils.getToken(rechargeRequest.getUserId().toString()), ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse subBalance(WithDrawRequest withDrawRequest) {
        try {
            userMapper.updateSubBalanceByUserId(withDrawRequest.getUserId(), withDrawRequest.getMoney());
            rechargeSerialMapper.insertRechargeSerial(OperationTypeEnum.WITHDRAWAL.getCode(), withDrawRequest.getMoney(),withDrawRequest.getUserId());
        } catch (Exception e) {
            log.error("【提现接口】系统异常{}:",e.getMessage());
            throw new OrderException(ResponseCodeEnum.CHECK_SYSTEM.getCode());
        }
        return new DataResponse(uuidUtils.getToken(withDrawRequest.getUserId().toString()), ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse registerAccount(RegisterAcountRequest registerAcountRequest) {
        User accountNews = null;
        try {
            User user = userMapper.getUser(registerAcountRequest.getUserName());
            if (!Objects.isNull(user)){
                return new DataResponse(ResponseCodeEnum.ACCOUNT_EXIT.getCode());
            }
            accountNews = new User();
            accountNews.setUsername(registerAcountRequest.getUserName());
            accountNews.setPassword(registerAcountRequest.getPassword());
            userMapper.insertNews(accountNews);
        } catch (Exception e) {
            log.error("【账号注册】异常:{}",e.getMessage());
            throw new AccountException(ResponseCodeEnum.CHECK_SYSTEM.getCode());
        }
        return new DataResponse(uuidUtils.getToken(accountNews.getId().toString()),ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse freezeAccount(FreezeAcountRequest freezeAcountRequest) {
        userMapper.updateAccountStatus(Long.parseLong(freezeAcountRequest.getUserId()) ,"1");
        return new DataResponse(uuidUtils.getToken(freezeAcountRequest.getUserId()),ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse resetPassword(ResetPasswordRequest resetPasswordRequest) {
        User user = null;
        try {
            user = userMapper.getUser(resetPasswordRequest.getUserName());
            if (Objects.isNull(user)){
                return new DataResponse(ResponseCodeEnum.COUNT_NOT_EXIST.getCode());
            }
            userMapper.updatePassword(user.getId(),resetPasswordRequest.getPassword());
        } catch (Exception e) {
            log.error("【账号注册】异常:{}",e.getMessage());
            throw new AccountException(ResponseCodeEnum.CHECK_SYSTEM.getCode());
        }
        return new DataResponse(uuidUtils.getToken(user.getId().toString()),ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse getAccountSerial(AccountSerialRequest request) {
        List<RechargeSerial> serial = new ArrayList<>();
        if (RechargeSerialTypeEnum.ALL.getCode().equals(request.getSerialType())){
            getAllRechargeSerial(serial,request);
        }else if (RechargeSerialTypeEnum.RECHARGE.getCode().equals(request.getSerialType())){
            getRechargeSerial(serial,request);
        }else if (RechargeSerialTypeEnum.PUSH.getCode().equals(request.getSerialType())){
            getPushSerial(serial,request);
        }else if (RechargeSerialTypeEnum.ACCEPT.getCode().equals(request.getSerialType())){
            getAcceptRechargeSerial(serial,request);
        }else if (RechargeSerialTypeEnum.WITHDRAW.getCode().equals(request.getSerialType())){
            getWithDrawSerial(serial,request);
        }
        Collections.sort(serial,new RechargeSerialCreateTimeComparator());
        return new DataResponse(serial,uuidUtils.getToken(request.getUserId().toString()),ResponseCodeEnum.success.getCode());
    }

    /**
     * 获取发单数据流水
     * @param serial
     * @param request
     */
    private void getPushSerial(List<RechargeSerial> serial, AccountSerialRequest request) {
        ArrayList<String> list = new ArrayList<>();
        list.add(OrderStatusEnum.OVER.getCode());
        List<ShopOrder> orderList = orderMapper.selectOrderByUserIdAndOrderTypeAndOrderStatus(request.getUserId().toString(), null, list);
        assembleData(serial,orderList,RechargeSerialTypeEnum.PUSH.getCode());
    }

    /**
     * 获取接单类型流水
     * @param serial
     * @param request
     */
    private void getAcceptRechargeSerial(List<RechargeSerial> serial, AccountSerialRequest request) {
        List<ShopOrder> orderList  = orderMapper.selectOrderByAdvisersId(request.getUserId().toString(), OrderStatusEnum.OVER.getCode());
        assembleData(serial,orderList,RechargeSerialTypeEnum.ACCEPT.getCode());
    }

    /**
     * 获取充值金额流水
     * @param serial
     * @param request
     */
    private void getRechargeSerial(List<RechargeSerial> serial, AccountSerialRequest request) {
        ArrayList<String> list = new ArrayList<>(); list.add(RechargeSerialTypeEnum.RECHARGE.getCode());
        serial.addAll(rechargeSerialMapper.selectRechargeSerialByUserId(request.getUserId(),list));
    }

    /**
     * 获取提现金额流水
     * @param serial
     * @param request
     */
    private void getWithDrawSerial(List<RechargeSerial> serial, AccountSerialRequest request) {
        ArrayList<String> list = new ArrayList<>(); list.add(RechargeSerialTypeEnum.WITHDRAW.getCode());
        serial.addAll(rechargeSerialMapper.selectRechargeSerialByUserId(request.getUserId(),list));
    }

    /**
     * 获取所有类型的金额流水
     * @param request
     * @return
     */
    private List<RechargeSerial> getAllRechargeSerial(List<RechargeSerial> serial,AccountSerialRequest request) {
        // 获取充值提现流水
        ArrayList<String> list = new ArrayList<>(); list.add(RechargeSerialTypeEnum.RECHARGE.getCode());list.add(RechargeSerialTypeEnum.WITHDRAW.getCode());
        serial.addAll(rechargeSerialMapper.selectRechargeSerialByUserId(request.getUserId(),list));
        // 获取发单流水
        list.clear();list.add(OrderStatusEnum.OVER.getCode());
        List<ShopOrder> orderList = orderMapper.selectOrderByUserIdAndOrderTypeAndOrderStatus(request.getUserId().toString(), null, list);
        assembleData(serial,orderList,RechargeSerialTypeEnum.PUSH.getCode());
        // 获取接单流水
        orderList.clear();
        orderList = orderMapper.selectOrderByAdvisersId(request.getUserId().toString(), OrderStatusEnum.OVER.getCode());
        assembleData(serial,orderList,RechargeSerialTypeEnum.ACCEPT.getCode());
        return serial;
    }

    /**
     * 拼接数据集
     * @param serial
     * @param orderList
     * @param type
     */
    private void assembleData(List<RechargeSerial> serial,List<ShopOrder> orderList, String type) {
        for (int i = 0; i < orderList.size(); i++) {
            RechargeSerial rechargeSerial = new RechargeSerial();
            rechargeSerial.setOperationType(type);
            rechargeSerial.setMount(BigDecimal.valueOf(orderList.get(i).getAward()));
            rechargeSerial.setCreateTime(orderList.get(i).getCreateTime());
            serial.add(rechargeSerial);
        }
    }


    @Override
    public DataResponse getUserInfo(UserInfoRequest userInfoRequest) {
        User user = null;
        try {
            user = userMapper.getUserById(userInfoRequest.getUserId());
        } catch (Exception e) {
            log.error("【用户信息请求】异常:{}",e.getMessage());
            throw new AccountException(ResponseCodeEnum.CHECK_SYSTEM.getCode());
        }
        return new DataResponse(user,uuidUtils.getToken(userInfoRequest.getUserId().toString()),ResponseCodeEnum.success.getCode());
    }

    @Override
    public DataResponse chanceAccountStatus(ChanceAccountStatusRequest chanceAccountStatusRequest) {
        try {
            userMapper.updateAccountStatus(chanceAccountStatusRequest.getUserId(), "1");
        } catch (Exception e) {
            log.error("【更改账户状态】异常:{}",e.getMessage());
            throw new AccountException(ResponseCodeEnum.CHECK_SYSTEM.getCode());
        }
        return new DataResponse(uuidUtils.getToken(chanceAccountStatusRequest.getUserId().toString()),ResponseCodeEnum.success.getCode());
    }
}
